package com.springboot.autoconfigure.oss.service.impl;

import cn.cqzaier.util.WebDavUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.googlecode.sardine.DavResource;
import com.springboot.autoconfigure.oss.config.OssConfigPropertis;
import com.springboot.autoconfigure.oss.config.WebdavConfigPropertis;
import com.springboot.autoconfigure.oss.model.FileInfo;
import com.springboot.autoconfigure.oss.model.FileOssOperationStatus;
import com.springboot.autoconfigure.oss.model.FileUploadStatus;
import com.springboot.autoconfigure.oss.service.AbstractInitClientServer;
import com.springboot.autoconfigure.oss.service.FileResolveService;
import com.springboot.autoconfigure.oss.service.OssApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.*;

@Slf4j
public class WebDavApiServiceImpl extends FileResolveService implements OssApiService<WebdavConfigPropertis>, AbstractInitClientServer<WebDavUtil> {

    private final WebdavConfigPropertis webdavConfigPropertis;
    private final OssConfigPropertis ossConfigPropertis;
    private WebDavUtil webDavUtil;

    public WebDavApiServiceImpl(WebdavConfigPropertis webdavConfigPropertis, OssConfigPropertis ossConfigPropertis) {
        this.webdavConfigPropertis = webdavConfigPropertis;
        this.ossConfigPropertis = ossConfigPropertis;
    }


    @Override
    public WebDavUtil getinit() {
//        if (webDavUtil != null) {
//            return webDavUtil;
//        }
        WebDavUtil.Config config = WebDavUtil.Config.builder().baseUrl(webdavConfigPropertis.getBaseUrl())
                .userName(webdavConfigPropertis.getUserName()).password(webdavConfigPropertis.getPassword()).build();
        webDavUtil = new WebDavUtil(config);
        return webDavUtil;
    }

    /**
     * 生成文件名称
     *
     * @param file
     * @return
     */
    public String getFileName(File file) {
        String fileName = getFileNameString(file);
        //指定的路径上传
        fileName = getFolderName(fileName);
        return fileName;
    }

    /**
     * 文件夹路径
     * @param fileName
     * @return
     */
    private String getFolderName(String fileName) {
        if (!StrUtil.isEmptyIfStr(ossConfigPropertis.getFolderPathName())) {
            fileName = ossConfigPropertis.getFolderPathName() + "/" + fileName;
        }
        return fileName;
    }

    /**
     * 生成指定路径的文件名称
     *
     * @param file
     * @return
     */
    public String getAbsoulteFileName(File file,String path) {
        String fileName = getFileNameString(file);
        StringBuilder stringBuilder = new StringBuilder();
        if (!ossConfigPropertis.getFolderPathName().endsWith("/"))
            stringBuilder.append("/");
        //指定的路径上传
        if (!StrUtil.isEmptyIfStr(ossConfigPropertis.getFolderPathName())) {
            stringBuilder.append(ossConfigPropertis.getFolderPathName());
        }
        stringBuilder.append(path);
        if (!path.endsWith("/"))
            stringBuilder.append("/");
        stringBuilder.append(fileName);
        fileName = stringBuilder.toString();
        return fileName;
    }


    @Override
    public FileUploadStatus uploadFile(URL url) {
        File fileByUrl = null;
        FileUploadStatus fileUploadStatus = null;
        try {
            fileByUrl = getFileByUrl(url);
            fileUploadStatus = uploadFile(fileByUrl);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            fileByUrl.delete();
        }

        return fileUploadStatus;
    }

    @Override
    public FileUploadStatus uploadFile(URL url, String filePrix) {
        return null;
    }

    @Override
    public FileUploadStatus uploadFile(File file) {
        String upload = null;
        try {
            upload = getinit().upload(WebDavUtil.CommonUtil.getAbsolutePath(webdavConfigPropertis.getBaseUrl() + webdavConfigPropertis.getPath(), getFileName(file)), new FileInputStream(file));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        FileUploadStatus suceess = FileUploadStatus.suceess();
        suceess.setUrlIsPublic(true);
        suceess.setFileKey(upload);
        suceess.setFileName(file.getName());
        if (suceess.isUrlIsPublic()) {
            suceess.setUrl(getDownloadURL(upload));
        }
        getUploadUrl(suceess,upload);
        return suceess;
    }

   

    @Override
    public List<FileInfo> getBucketSpaceFile(String prefix, int limit) {
        ArrayList<FileInfo> result = new ArrayList<>();
        try {
            String absolutePath = WebDavUtil.CommonUtil.getAbsolutePath(webdavConfigPropertis.getBaseUrl() + webdavConfigPropertis.getPath(),getFolderName(prefix));
            List<DavResource> davResources = getinit().listFile(absolutePath);
            for (DavResource davResource : davResources) {
                 FileInfo fileInfo = new FileInfo();
                fileInfo.setFileKey(davResource.getAbsoluteUrl());
                result.add(fileInfo);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    @Override
    public FileUploadStatus uploadAbsoulteFilePath(File file, String filePath) {
        if (!filePath.startsWith("/")){
            filePath ="/"+filePath;
        }
        FileUploadStatus suceess = FileUploadStatus.suceess();

        String upload = null;
        try {
            String absolutePath = WebDavUtil.CommonUtil.getAbsolutePath(webdavConfigPropertis.getBaseUrl() + webdavConfigPropertis.getPath(), getAbsoulteFileName(file,filePath));
            upload = getinit().upload(absolutePath, new FileInputStream(file));
            suceess.setFileKey(absolutePath);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        suceess.setUrlIsPublic(true);
        suceess.setFileName(upload);
        if (suceess.isUrlIsPublic()) {
            suceess.setUrl(getDownloadURL(upload));
        } else {

        }
        return suceess;
    }

    @Override
    public FileUploadStatus uploadFile(File file, String fileName) {
        String upload = null;
        try {
            upload = getinit().upload(WebDavUtil.CommonUtil.getAbsolutePath(webdavConfigPropertis.getBaseUrl() + webdavConfigPropertis.getPath(), fileName), new FileInputStream(file));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        FileUploadStatus suceess = FileUploadStatus.suceess();
        suceess.setUrlIsPublic(true);
        suceess.setFileKey(upload);
        suceess.setFileName(fileName);
        if (suceess.isUrlIsPublic()) {
            suceess.setUrl(getDownloadURL(upload));
        }
        // 适配接口定义 复写接口方法
        getUploadUrl(suceess,upload);
        return suceess;
    }

    @Override
    public void getUploadUrl(FileUploadStatus fileUploadStatus, String uploadResponseInfo) {

    }

    @Override
    public FileUploadStatus uploadFileAndCallBack(File file, String callbackUrl) {
        return null;
    }

    @Override
    public List<String> findFile(String... fileNames) {
        ArrayList<String> result = new ArrayList<>();
        for (String fileName : fileNames) {
            String absoluteUrl = findByUrl(fileName);
            if (StringUtils.isNotBlank(absoluteUrl)) {
                result.add(absoluteUrl);
            }
        }
        return result;

    }

    private String findByUrl(String fileName) {
        List<DavResource> davResources = null;
        try {
            davResources = getinit().listFile(fileName);
        } catch (IOException e) {
        }
        if(CollectionUtil.isEmpty(davResources))return null;
        String absoluteUrl = davResources.stream().findFirst().get().getAbsoluteUrl();
        return absoluteUrl;
    }


    @Override
    public FileUploadStatus findFileByKey(String fileKey) {
        FileUploadStatus suceess = FileUploadStatus.suceess();
        suceess.setUrlIsPublic(true);
        // get url
        suceess.setUrl(getDownloadURL(fileKey));
        suceess.setFileKey(fileKey);
        return suceess;
    }

    /**
     * TODO  该方法着重看看
     * 获取下载链接
     * @param absoluteUrl
     *          example：
     *              absoluteUrl  https://cloud.lpwyj.top:443/dav/ali/taoke_01a6fac2-0b1f-4442-854f-4f362131c916165865402538937540032.jpg
     *              downloadURL  https://cloud.lpwyj.top/d/ali/taoke_01a6fac2-0b1f-4442-854f-4f362131c916165865402538937540032.jpg
     * @return
     */
    public static String getDownloadURL(String absoluteUrl){
        String cloudNativeUrl = null;
        if(StringUtils.isBlank(absoluteUrl))return null;
        try {
            log.info("down-absoluteUrl:{}",absoluteUrl);
            absoluteUrl = getWebDownloadUrlStr(absoluteUrl);
            cloudNativeUrl= cn.cqzaier.util.URLUtil.getlocatonUrl(absoluteUrl);
            System.out.println(cloudNativeUrl);
            log.info("down-cloudNativeUrl-return :{}",cloudNativeUrl);
            return cloudNativeUrl;
             // test download
//            DownLoadFileUtils.downLoadByUrl(cloudNativeUrl,"D:\\test\\",StringUtils.substringAfterLast(absoluteUrl,"/"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
            log.error("down-cloudNativeUrl-error:{}",e.getMessage());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("down-cloudNativeUrl-return :{}",cloudNativeUrl);
        return cloudNativeUrl;

    }


    /**
     * 网页端 下载地址
     * @param absoluteUrl
     * @return
     * @throws MalformedURLException
     */
    public static String getWebDownloadUrlStr(String absoluteUrl) throws MalformedURLException {
        URL url = new URL(absoluteUrl);
        URI host = URLUtil.getHost(url);
        String childPath = StringUtils.substringAfter(absoluteUrl, "/dav");
        absoluteUrl = host +"/d"+childPath;
        log.info("down-cloudNativeUrl:{}", absoluteUrl);
        return absoluteUrl;
    }

//    public static void main(String[] args) {
////        getDownloadURL("https://cloud.lpwyj.top/d/ali/taoke_01a6fac2-0b1f-4442-854f-4f362131c916165865402538937540032.jpg");
//        getDownloadURL("https://cloud.lpwyj.top:443/dav/123study/test.jpg");
//    }



    @Override
    public FileOssOperationStatus delFile(String... fileNames) {
        for (String fileName : fileNames) {
            try {
                getinit().delete(fileName);
            } catch (IOException e) {

            }
        }
        return FileOssOperationStatus.suceess();
    }

    public String downWebdavUrlLocal(String filePath) throws IOException {
        String s = StringUtils.substringAfterLast(filePath, "/");
        File file = new File(webdavConfigPropertis.getStoreLoaclPath(), s);
        if (StringUtils.isBlank(webdavConfigPropertis.getStoreLoaclPath())){
            file = new File(FileUtil.getUserHomePath(), s);
        }
        // 可以根据环境配置配置下载路径
        if (StringUtils.isNotBlank(System.getProperty("oss.webdav.storeLoaclPath"))) {
            file = new File(System.getProperty("oss.webdav.storeLoaclPath"), s);
        }
        getinit().download2Stream(filePath, new FileOutputStream(file));
        return file.getAbsolutePath();
    }
}
